home *** CD-ROM | disk | FTP | other *** search
/ PC PowerPlay 58 / pcpp58a.iso / extras / quake 3 source / Q3A_ToolSource.exe / Main / p3dlib.c < prev    next >
Encoding:
C/C++ Source or Header  |  2001-01-02  |  5.3 KB  |  318 lines

  1. #include "p3dlib.h"
  2.  
  3. #include <io.h>
  4. #include <stdlib.h>
  5. #include <stdio.h>
  6. #include <string.h>
  7.  
  8. #define MAX_POLYSETS 64
  9.  
  10. typedef struct
  11. {
  12.     long len;
  13.  
  14.     int     numPairs;
  15.     char polysetNames[MAX_POLYSETS][256];
  16.     char shaders[MAX_POLYSETS][256];
  17.  
  18.     char *buffer, *curpos;
  19. } p3d_t;
  20.  
  21. static p3d_t p3d;
  22.  
  23. static int P3DProcess();
  24. static int P3DGetToken( int restOfLine );
  25.  
  26. static char s_token[1024];
  27. static int    s_curpair;
  28.  
  29. /*
  30. ** P3DLoad
  31. **
  32. */
  33. int P3DLoad( const char *filename )
  34. {
  35.     FILE *fp = fopen( filename, "rb" );
  36.  
  37.     if ( !fp )
  38.         return 0;
  39.  
  40.     memset( &p3d, 0, sizeof( p3d ) );
  41.  
  42.     p3d.len = filelength( fileno( fp ) );
  43.  
  44.     p3d.curpos = p3d.buffer = malloc( p3d.len );
  45.  
  46.     if ( fread( p3d.buffer, p3d.len, 1, fp ) != 1 )
  47.     {
  48.         fclose( fp );
  49.         return 0;
  50.     }
  51.  
  52.     fclose( fp );
  53.  
  54.     return P3DProcess();
  55. }
  56.  
  57. /*
  58. ** P3DClose
  59. **
  60. */
  61. void P3DClose()
  62. {
  63.     if ( p3d.buffer )
  64.     {
  65.         free( p3d.buffer );
  66.         p3d.buffer = 0;
  67.     }
  68. }
  69.  
  70. int CharIsTokenDelimiter( int ch )
  71. {
  72.     if ( ch <= 32 )
  73.         return 1;
  74.     return 0;
  75. }
  76.  
  77. int P3DSkipToToken( const char *name )
  78. {
  79.     while ( P3DGetToken( 0 ) )
  80.     {
  81.         if ( !_strcmpi( s_token, name ) )
  82.             return 1;
  83.     }
  84.  
  85.     return 0;
  86. }
  87.  
  88. /*
  89. ** P3DGetToken
  90. **
  91. */
  92. int P3DGetToken( int restOfLine )
  93. {
  94.     int i = 0;
  95.  
  96.     if ( p3d.buffer == 0 )
  97.         return 0;
  98.  
  99.     if ( ( p3d.curpos - p3d.buffer ) == p3d.len )
  100.         return 0;
  101.  
  102.     // skip over crap
  103.     while ( ( ( p3d.curpos - p3d.buffer ) < p3d.len ) &&
  104.             ( *p3d.curpos <= 32 ) )
  105.     {
  106.         p3d.curpos++;
  107.     }
  108.  
  109.     while ( ( p3d.curpos - p3d.buffer ) < p3d.len )
  110.     {
  111.         s_token[i] = *p3d.curpos;
  112.  
  113.         p3d.curpos++;
  114.         i++;
  115.  
  116.         if ( ( CharIsTokenDelimiter( s_token[i-1] ) && !restOfLine ) ||
  117.              ( ( s_token[i-1] == '\n' ) ) )
  118.         {
  119.             s_token[i-1] = 0;
  120.             break;
  121.         }
  122.     }
  123.  
  124.     s_token[i] = 0;
  125.  
  126.     return 1;
  127. }
  128.  
  129. int P3DGetNextPair( char **psetName, char **associatedShader )
  130. {
  131.     if ( s_curpair < p3d.numPairs )
  132.     {
  133.         *psetName = p3d.polysetNames[s_curpair];
  134.         *associatedShader = p3d.shaders[s_curpair];
  135.         s_curpair++;
  136.         return 1;
  137.     }
  138.  
  139.     return 0;
  140. }
  141.  
  142. int P3DSkipToTokenInBlock( const char *name )
  143. {
  144.     int iLevel = 0;
  145.  
  146.     while ( P3DGetToken( 0 ) ) 
  147.     {
  148.         if ( !_strcmpi( s_token, "}" ) )
  149.             iLevel--;
  150.         else if ( !_strcmpi( s_token, "{" ) )
  151.             iLevel++;
  152.  
  153.         if ( !_strcmpi( s_token, name ) )
  154.             return 1;
  155.  
  156.         if ( iLevel == 0 )
  157.         {
  158.             return 0;
  159.         }
  160.     }
  161.  
  162.     return 0;
  163. }
  164.  
  165. /*
  166. ** P3DProcess
  167. **
  168. ** Nothing fancy here.
  169. */
  170. int P3DProcess()
  171. {
  172.  
  173.     s_curpair = 0;
  174.  
  175.     // first token should be a string
  176.     P3DGetToken( 1 );        // Voodoo Ascii File
  177.  
  178.     // skip to the first Obj declaration
  179.     while ( P3DGetToken( 0 ) )
  180.     {
  181.         if ( !_strcmpi( s_token, "Obj" ) )
  182.         {
  183.             int j = 0, k = 0;
  184.  
  185.             if ( P3DSkipToToken( "Text" ) )
  186.             {
  187.                 if ( P3DSkipToTokenInBlock( "TMap" ) )
  188.                 {
  189.                     char *p;
  190.  
  191.                     if ( !P3DSkipToToken( "Path" ) )
  192.                         return 0;
  193.  
  194.                     if ( !P3DGetToken( 1 ) )
  195.                         return 0;
  196.  
  197.                     while ( s_token[j] != 0 )
  198.                     {
  199.                         if ( s_token[j] == '\\' )
  200.                         {
  201.                             j++;
  202.                             p3d.shaders[p3d.numPairs][k] = '/';
  203.                         }
  204.                         else
  205.                         {
  206.                             p3d.shaders[p3d.numPairs][k] = s_token[j];
  207.                         }
  208.                         j++;
  209.                         k++;
  210.                     }
  211.                     p3d.shaders[p3d.numPairs][k] = 0;
  212.  
  213.                     //
  214.                     // strip off any explicit extensions
  215.                     //
  216.                     if ( ( p = strrchr( p3d.shaders[p3d.numPairs], '/' ) ) != 0 )
  217.                     {
  218.                         while ( *p )
  219.                         {
  220.                             if ( *p == '.' ) 
  221.                             {
  222.                                 *p = 0;
  223.                                 break;
  224.                             }
  225.                             p++;
  226.                         }
  227.                     }
  228.  
  229.                     //
  230.                     // skip to the end of the Object and grab its name
  231.                     //
  232.                     if ( !P3DSkipToToken( "Name" ) )
  233.                         return 0;
  234.  
  235.                     if ( P3DGetToken( 0 ) )
  236.                     {
  237.                         // strip off leading 'Obj_' if it exists
  238.                         if ( strstr( s_token, "Obj_" ) == s_token )
  239.                             strcpy( p3d.polysetNames[p3d.numPairs], s_token + strlen( "Obj_" ) );
  240.                         else
  241.                             strcpy( p3d.polysetNames[p3d.numPairs], s_token );
  242.  
  243.                         // strip off trailing unused color information
  244. //                        if ( strrchr( p3d.polysetNames[p3d.numPairs], '_' ) != 0 )
  245. //                            *strrchr( p3d.polysetNames[p3d.numPairs], '_' ) = 0;
  246.  
  247.                         p3d.numPairs++;
  248.                     }
  249.                     else
  250.                     {
  251.                         return 0;
  252.                     }
  253.                 }
  254.             }
  255.         }
  256.     }
  257.  
  258.     s_curpair = 0;
  259.  
  260.     return 1;
  261. }
  262.  
  263. #if 0
  264. void SkinFromP3D( const char *file )
  265. {
  266.     char filename[1024];
  267.     char *psetName, *associatedShader;
  268.  
  269.     /*
  270.     ** a P3D file contains a list of polysets, each with a list of associated
  271.     ** texture names that constitute it's
  272.     **
  273.     ** Thus:
  274.     **
  275.     ** P3D file -> skin
  276.     ** polyset  -> polyset
  277.     **   texture -> texture.SHADER becomes polyset's shader
  278.     */
  279.     sprintf( filename, "%s/%s", g_cddir, file );
  280.  
  281.     if ( !P3DLoad( filename ) )
  282.         Error( "unable to load '%s'", filename );
  283.  
  284.     while ( P3DGetNextPair( &psetName, &associatedShader ) )
  285.     {
  286.         int i;
  287.  
  288.         // find the polyset in the object that this particular pset/shader pair
  289.         // corresponds to and append the shader to it
  290.         for ( i = 0; i < g_data.model.numSurfaces; i++ )
  291.         {
  292.             if ( !_strcmpi( g_data.surfData[i].header.name, psetName) )
  293.             {
  294.                 char *p;
  295.  
  296.                 if ( strstr( associatedShader, gamedir + 1 ) )
  297.                 {
  298.                     p = strstr( associatedShader, gamedir + 1 ) + strlen( gamedir ) - 1;
  299.                 }
  300.                 else
  301.                 {
  302.                     p = associatedShader;
  303.                 }
  304.  
  305.                 strcpy( g_data.surfData[i].shaders[g_data.surfData[i].header.numShaders].name, p );
  306.  
  307.                 g_data.surfData[i].header.numShaders++;
  308.             }
  309.         }
  310.  
  311.     }
  312.  
  313.     P3DClose();
  314. }
  315. #endif
  316.  
  317.  
  318.